import { _decorator, Component, EventTouch, Label, math, Node, Prefab, tween, v2, v3, Vec2, Vec3 } from 'cc';
import { PoolManager } from './PoolManager';
import { FallItem } from './FallItem';
import { EventManager, MyEvent } from './EventManager';
import { BallMotion } from './BallMotion';
const { ccclass, property } = _decorator;

@ccclass('FallItemManager')
export class FallItemManager extends Component {
    public static Instance: FallItemManager = null;

    @property(Prefab)
    ItemPrefab: Prefab = null;

    @property(Node)
    LeftUp: Node = null;

    @property(Node)
    RightDown: Node = null;

    @property(Node)
    Ball: Node = null;

    @property
    lifetime: number = 5;

    @property
    InvincibleTime: number = 0.1;

    @property
    speed: number = 10;

    @property
    Interval: number = 1;

    @property
    gravity: number = -3;

    @property
    repulsionConstant: number = 100;

    @property
    subx: number = 100;

    @property
    suby: number = 100;

    @property
    dis: number = 300;

    @property
    StartNum: number = 1;

    @property
    AddNum: number = 1;

    @property
    MaxCount: number = 1000;

    @property
    OnceCount: number = 5;

    @property(Node)
    AredNode: Node = null;

    @property(Node)
    StartNode: Node = null;

    @property(Node)
    Item: Node = null;

    public IsStart: boolean = false;

    private _timer: number = 0;
    private _createTimer: number = 0;
    private _initPos: Vec3;
    private _count: number = 0;
    private _interval: number = 0.01;
    private _score: number = 0;
    private _maxY: number = 0;
    private _curCount: number = 0;
    private _isPause: boolean = false;

    private _leftUpPos: Vec2 = new Vec2();
    private _rightDownPos: Vec2 = new Vec2();
    private _touchStart: Vec2 = new Vec2();

    protected onLoad(): void {
        FallItemManager.Instance = this;

        this._leftUpPos = v2(this.LeftUp.getWorldPosition().x, this.LeftUp.getWorldPosition().y);
        this._rightDownPos = v2(this.RightDown.getWorldPosition().x, this.RightDown.getWorldPosition().y);

        this.AredNode.once(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.AredNode.once(Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.AredNode.once(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
        tween(this.StartNode)
            .to(1, { scale: v3(1.2, 1.2, 1.2) }, { easing: `sineIn` })
            .to(1, { scale: v3(1, 1, 1) }, { easing: `sineIn` })
            .union()
            .repeatForever()
            .start();
    }

    protected start(): void {
        this._initPos = this.node.getWorldPosition();
        this.addItems(this.StartNum);
        PoolManager.Instance.preload(this.ItemPrefab, this.MaxCount);
    }

    protected update(dt: number): void {
        if (!this.IsStart) return;
        if (this._isPause) return;
        this._timer += dt;
        this._createTimer += dt;

        if (this._timer > this.Interval) {
            this._timer = 0;
            this.StartNum += this.AddNum;
            this.addItems(this.StartNum);
        }

        if (this._count > this.OnceCount) {
            this._createTimer = 0;
            this._count -= this.OnceCount;
            this.createItems(this.OnceCount);
        }
    }

    addItems(count: number) {
        this._count += count;
    }

    createItems(count: number) {
        for (let i = 0; i < count; i++) {
            this.createItem();
        }
    }

    createItem() {
        if (this._curCount > this.MaxCount) return;
        this._curCount++;

        const node: Node = PoolManager.Instance.get(this.ItemPrefab);
        const worldPos: Vec3 = this._initPos.clone().add3f(math.randomRange(-540, 540), 0, 0);
        node.getComponent(FallItem).init(this.node, worldPos, this.lifetime, this.speed, this.gravity, this.repulsionConstant, this.subx, this.suby, this.dis);
    }

    removeItem(target: Node) {
        PoolManager.Instance.put(target);
        this._curCount--;
    }

    getDis(other: Node): number {
        return Vec3.distance(this.Ball.getWorldPosition(), other.getWorldPosition());
    }

    getDir(other: Node): Vec3 {
        return other.getWorldPosition().subtract(this.Ball.getWorldPosition()).normalize();
    }

    checkOut(pos: Vec3): boolean {
        return pos.x < this._leftUpPos.x - 100 || pos.x > this._rightDownPos.x + 100 || pos.y < this._rightDownPos.y - 100;
    }

    private pause() {
        this._isPause = !this._isPause;
    }

    protected onEnable(): void {
        EventManager.on(MyEvent.PAUSE, this.pause, this);
    }

    protected onDisable(): void {
        EventManager.off(MyEvent.PAUSE, this.pause, this);
    }

    onTouchStart(event: EventTouch) {
        this._touchStart = event.getUILocation();
    }

    onTouchEnd(event: EventTouch) {
        // this._touchStart = event.getUILocation();
        const parce: Vec2 = event.getUILocation().subtract(this._touchStart).normalize().multiplyScalar(2);
        this.Item.getComponent(BallMotion).velocity = parce;
        this.AredNode.active = false;
        this.IsStart = true;
    }
}


